"""
设备资产对话框 - 统一样式版本
"""

import logging
from typing import Dict, Any, Optional
from PyQt5.QtWidgets import (
    QFormLayout, QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox,
    QTextEdit, QGroupBox, QVBoxLayout, QHBoxLayout, QListWidget,
    QListWidgetItem, QSplitter, QWidget, QLabel
)
from PyQt5.QtCore import Qt, pyqtSignal

from src.app.ui.base_dialog import BaseDialog
from src.app.modules.asset.service import AssetService
from src.app.modules.asset.utils import AssetUtils

logger = logging.getLogger(__name__)

class AssetDialog(BaseDialog):
    """设备资产编辑对话框 - 统一样式版本"""
    
    # 信号定义
    asset_saved = pyqtSignal(str)  # 资产保存信号
    
    def __init__(self, parent=None, asset_id: Optional[str] = None):
        self.asset_id = asset_id
        self.asset_service = AssetService()
        self.asset_utils = AssetUtils()
        self.is_edit = asset_id is not None
        
        # 资产类型映射
        self.asset_type_mapping = {
            '服务器': 'server',
            '安全设备': 'security_device',
            '虚拟机管理平台': 'vm_platform',
            '分布式存储': 'distributed_storage',
            'PC机': 'pc',
            '网络设备': 'network_device'
        }
        
        # 设置对话框标题和尺寸
        title = "编辑设备资产" if self.is_edit else "新增设备资产"
        super().__init__(parent, title=title, width=800, height=600)
        
        # 如果是编辑模式，加载数据
        if asset_id:
            self.load_asset_data()
    
    def create_content_widget(self):
        """创建内容区域"""
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        
        # 左侧：基本信息
        left_widget = self.create_basic_info_widget()
        splitter.addWidget(left_widget)
        
        # 右侧：设备组成关系
        right_widget = self.create_composition_widget()
        splitter.addWidget(right_widget)
        
        # 设置分割器比例
        splitter.setSizes([500, 300])
        
        return splitter
    
    def create_basic_info_widget(self):
        """创建基本信息组件"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 基本信息组
        basic_group = QGroupBox("基本信息")
        basic_layout = QFormLayout(basic_group)
        
        # 资产类型
        self.asset_type_combo = QComboBox()
        self.asset_type_combo.addItems(list(self.asset_type_mapping.keys()))
        basic_layout.addRow("资产类型*:", self.asset_type_combo)
        
        # 资产名称
        self.asset_name_edit = QLineEdit()
        self.asset_name_edit.setPlaceholderText("请输入资产名称")
        basic_layout.addRow("资产名称*:", self.asset_name_edit)
        
        # 资产编码
        self.asset_code_edit = QLineEdit()
        self.asset_code_edit.setPlaceholderText("请输入资产编码")
        basic_layout.addRow("资产编码*:", self.asset_code_edit)
        
        # 型号
        self.model_edit = QLineEdit()
        self.model_edit.setPlaceholderText("请输入设备型号")
        basic_layout.addRow("型号:", self.model_edit)
        
        # 部门
        self.department_combo = QComboBox()
        self.department_combo.setEditable(True)
        self.load_departments()
        basic_layout.addRow("部门:", self.department_combo)
        
        # 用途描述
        self.purpose_edit = QTextEdit()
        self.purpose_edit.setPlaceholderText("请输入用途描述")
        self.purpose_edit.setMaximumHeight(80)
        basic_layout.addRow("用途描述:", self.purpose_edit)
        
        layout.addWidget(basic_group)
        
        # 硬件信息组
        hardware_group = QGroupBox("硬件信息")
        hardware_layout = QFormLayout(hardware_group)
        
        # CPU核数
        self.cpu_cores_spin = QSpinBox()
        self.cpu_cores_spin.setRange(0, 1000)
        self.cpu_cores_spin.setValue(0)
        hardware_layout.addRow("CPU核数:", self.cpu_cores_spin)
        
        # 内存
        self.memory_spin = QDoubleSpinBox()
        self.memory_spin.setRange(0, 10000)
        self.memory_spin.setSuffix(" GB")
        self.memory_spin.setDecimals(1)
        self.memory_spin.setValue(0)
        hardware_layout.addRow("内存:", self.memory_spin)
        
        # 存储容量
        self.storage_spin = QDoubleSpinBox()
        self.storage_spin.setRange(0, 100000)
        self.storage_spin.setSuffix(" GB")
        self.storage_spin.setDecimals(1)
        self.storage_spin.setValue(0)
        hardware_layout.addRow("存储容量:", self.storage_spin)
        
        # 硬盘数量
        self.hdd_count_spin = QSpinBox()
        self.hdd_count_spin.setRange(0, 100)
        self.hdd_count_spin.setValue(0)
        hardware_layout.addRow("硬盘数量:", self.hdd_count_spin)
        
        # 硬盘规格
        self.hdd_specs_edit = QLineEdit()
        self.hdd_specs_edit.setPlaceholderText("如：1TB SATA")
        hardware_layout.addRow("硬盘规格:", self.hdd_specs_edit)
        
        layout.addWidget(hardware_group)
        
        return widget
    
    def create_composition_widget(self):
        """创建设备组成关系组件"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 标题
        title_label = QLabel("设备组成关系")
        title_font = QFont()
        title_font.setBold(True)
        title_label.setFont(title_font)
        layout.addWidget(title_label)
        
        # 说明
        info_label = QLabel("选择组成此设备集群的其他设备：")
        info_label.setStyleSheet("color: #666; font-size: 12px;")
        layout.addWidget(info_label)
        
        # 可选设备列表
        available_label = QLabel("可选设备:")
        layout.addWidget(available_label)
        
        self.available_list = QListWidget()
        self.available_list.setSelectionMode(QListWidget.MultiSelection)
        layout.addWidget(self.available_list)
        
        # 按钮
        button_layout = QHBoxLayout()
        
        self.add_btn = QPushButton("添加 →")
        self.add_btn.clicked.connect(self.add_composition)
        button_layout.addWidget(self.add_btn)
        
        self.remove_btn = QPushButton("← 移除")
        self.remove_btn.clicked.connect(self.remove_composition)
        button_layout.addWidget(self.remove_btn)
        
        layout.addLayout(button_layout)
        
        # 已选设备列表
        selected_label = QLabel("已选设备:")
        layout.addWidget(selected_label)
        
        self.selected_list = QListWidget()
        self.selected_list.setSelectionMode(QListWidget.MultiSelection)
        layout.addWidget(self.selected_list)
        
        # 加载可选设备
        self.load_available_assets()
        
        return widget
    
    def load_departments(self):
        """加载部门列表"""
        try:
            departments = self.asset_service.get_departments()
            self.department_combo.clear()
            self.department_combo.addItem("")
            for dept in departments:
                self.department_combo.addItem(dept)
        except Exception as e:
            logger.error(f"加载部门列表失败: {e}")
    
    def load_available_assets(self):
        """加载可选设备列表"""
        try:
            assets = self.asset_service.get_all_assets()
            
            self.available_list.clear()
            for asset in assets:
                # 排除当前编辑的资产
                if asset['asset_id'] == self.asset_id:
                    continue
                
                item = QListWidgetItem(
                    f"{asset['asset_name']} ({asset['asset_code']})"
                )
                item.setData(Qt.UserRole, asset['asset_id'])
                self.available_list.addItem(item)
                
        except Exception as e:
            logger.error(f"加载可选设备失败: {e}")
    
    def load_asset_data(self):
        """加载资产数据"""
        try:
            asset = self.asset_service.get_asset_by_id(self.asset_id)
            if not asset:
                self.show_error_message("错误", "设备资产不存在")
                return
            
            # 填充基本信息
            self.asset_type_combo.setCurrentText(self.asset_utils.get_asset_type_display(asset['asset_type']))
            self.asset_name_edit.setText(asset['asset_name'])
            self.asset_code_edit.setText(asset['asset_code'])
            self.model_edit.setText(asset.get('model', ''))
            
            # 部门
            dept = asset.get('department', '')
            index = self.department_combo.findText(dept)
            if index >= 0:
                self.department_combo.setCurrentIndex(index)
            else:
                self.department_combo.setCurrentText(dept)
            
            # 用途描述
            self.purpose_edit.setText(asset.get('purpose_desc', ''))
            
            # 硬件信息
            self.cpu_cores_spin.setValue(asset.get('cpu_cores', 0))
            self.memory_spin.setValue(asset.get('memory_gb', 0))
            self.storage_spin.setValue(asset.get('storage_capacity', 0))
            self.hdd_count_spin.setValue(asset.get('hard_disk_count', 0))
            self.hdd_specs_edit.setText(asset.get('hard_disk_specs', ''))
            
            # 设备组成关系
            composition = asset.get('device_composition', [])
            self.load_composition_assets(composition)
            
        except Exception as e:
            logger.error(f"加载资产数据失败: {e}")
            self.show_error_message("错误", f"加载数据失败: {str(e)}")
    
    def load_composition_assets(self, asset_ids):
        """加载设备组成关系"""
        try:
            self.selected_list.clear()
            
            for asset_id in asset_ids:
                asset = self.asset_service.get_asset_by_id(asset_id)
                if asset:
                    item = QListWidgetItem(
                        f"{asset['asset_name']} ({asset['asset_code']})"
                    )
                    item.setData(Qt.UserRole, asset['asset_id'])
                    self.selected_list.addItem(item)
                    
        except Exception as e:
            logger.error(f"加载设备组成关系失败: {e}")
    
    def add_composition(self):
        """添加设备组成关系"""
        selected_items = self.available_list.selectedItems()
        
        for item in selected_items:
            asset_id = item.data(Qt.UserRole)
            asset_name = item.text()
            
            # 检查是否已存在
            existing_items = self.selected_list.findItems(asset_name, Qt.MatchExactly)
            if existing_items:
                continue
            
            # 添加到已选列表
            new_item = QListWidgetItem(asset_name)
            new_item.setData(Qt.UserRole, asset_id)
            self.selected_list.addItem(new_item)
    
    def remove_composition(self):
        """移除设备组成关系"""
        selected_items = self.selected_list.selectedItems()
        
        for item in selected_items:
            row = self.selected_list.row(item)
            self.selected_list.takeItem(row)
    
    def get_form_data(self) -> Dict[str, Any]:
        """获取表单数据"""
        # 获取设备组成关系
        composition = []
        for i in range(self.selected_list.count()):
            item = self.selected_list.item(i)
            asset_id = item.data(Qt.UserRole)
            composition.append(asset_id)
        
        return {
            'asset_type': self.asset_type_mapping.get(self.asset_type_combo.currentText(), self.asset_type_combo.currentText()),
            'asset_name': self.asset_name_edit.text().strip(),
            'asset_code': self.asset_code_edit.text().strip(),
            'model': self.model_edit.text().strip(),
            'department': self.department_combo.currentText().strip(),
            'purpose_desc': self.purpose_edit.toPlainText().strip(),
            'cpu_cores': self.cpu_cores_spin.value() if self.cpu_cores_spin.value() > 0 else None,
            'memory_gb': self.memory_spin.value() if self.memory_spin.value() > 0 else None,
            'storage_capacity': self.storage_spin.value() if self.storage_spin.value() > 0 else None,
            'hard_disk_count': self.hdd_count_spin.value() if self.hdd_count_spin.value() > 0 else None,
            'hard_disk_specs': self.hdd_specs_edit.text().strip() or None,
            'device_composition': composition
        }
    
    def accept_data(self):
        """接受数据"""
        try:
            # 获取表单数据
            asset_data = self.get_form_data()
            
            # 验证数据
            is_valid, error_msg = self.asset_utils.validate_asset_data(asset_data)
            if not is_valid:
                self.show_error_message("验证失败", error_msg)
                return
            
            # 保存资产
            if self.asset_id:
                # 更新
                result = self.asset_service.update_asset(self.asset_id, asset_data)
            else:
                # 创建
                result = self.asset_service.create_asset(asset_data)
            
            if result['success']:
                self.show_success_message("成功", result['message'])
                self.asset_saved.emit(result.get('data', {}).get('asset_id', ''))
                super().accept_data()
            else:
                self.show_error_message("失败", result['message'])
                
        except Exception as e:
            logger.error(f"保存资产失败: {e}")
            self.show_error_message("错误", f"保存失败: {str(e)}")